| Designers > K2 Designer for SharePoint 2010 > Design Tools > Navigation Ribbon > Workflow Steps > User Tasks > Creating Custom User Tasks | Send feedback |
In order to create a custom User Task, it is important to know how to create a Custom Wizard in K2. See the document on creating a custom wizard for more detail. In addition, a Silverlight wizard and a Client Event Object needs to be created. Inject the following XML into ProcessExtenderEvent table with the ClientSide column set to True. The linking to the Categories and Context works the same as when creating a Custom Wizard.
Copy XML |
|---|
|
<Event> <EventPageDetails> <FormPlugin> <File>SourceCode.WebDesigner.DesignerPlugin.DefaultClientEvent.bin</File> 1. <PopupPlugins> <PopupPlugin>SourceCode.WebDesigner.DesignerPlugin.DefaultClientEvent.Page1</PopupPlugin> 2. </PopupPlugins> <Validator /> <InitData /> <EventWizard> <Assembly>SourceCode.WebDesigner.Authoring.ClientEventForms, Version=4.0.0.0 , Culture=neutral, PublicKeyToken=16a2c5aaaa1b130d</Assembly> 3. <Class>SourceCode.WebDesigner.Authoring.ClientEvent.DefaultClientEvent</Class> 4. </EventWizard> <Images> <Default>DefaultClientEvent32_orange.png</Default> 5. <Originator>DefaultClientEvent32_green.png</Originator> <Manager>DefaultClientEvent32_red.png</Manager> <Runtime>DefaultClientEvent32.png</Runtime> <Wizard>DefaultClientEvent64_green.png</Wizard> </Images> </FormPlugin> </EventPageDetails> </Event> |
| Node | What it is |
|---|---|
|
1. <File></File> |
The Silverlight UI plugin similar to the Wizards |
|
2. <PopupPlugin></PopupPlugin> |
The Pages you want to display , there can be more than one PopupPlugin node for each page. The data for the plugin will then be saved to the ActivityXML in the FormPluginData node in the process XML |
|
3. <Assembly></Assembly> |
The assembly and class which will be called on deployment |
|
4. <Class></Class> |
The Class in the assembly which will add the client event. This class must have the following method which conforms to the one implemented from the base class (CreateDynamicClientEvent)
|
|
5. <Default></Default> |
The icons must be 32x32 except the Wizard icon which must be 64x64. The 32x32 icons can be the same, it's just easier to differentiate between Originator, Manager etc if they are different |
Copy XML |
|---|
|
using System.Data; using System.Data.SqlClient; using System.IO; using System.Net; using System.Reflection; using System.Text; using System.Xml; using System.Xml.Linq; using SourceCode; using SourceCode.Configuration; using SourceCode.EnvironmentSettings.Client; using SourceCode.Framework; using SourceCode.Framework.Deployment; using SourceCode.ProjectSystem; using SourceCode.WebDesigner.Utils; using SourceCode.Workflow.Authoring; using SourceCode.Workflow.Common.Authentication; using SourceCode.Workflow.Common.WorkflowIntegration; using SourceCode.Workflow.Design; using SourceCode.Workflow.Design.SimpleRules; using SourceCode.Workflow.Expressions.Design; using SourceCode.Workflow.Functions.Design; using System; using System.Collections;
namespace SourceCode.WebDesigner.Authoring.ClientEvent { public class DefaultClientEvent : ClientEventBase, IClientEvent { public void CreateDynamicClientEvent(XmlDocument xmlProcess, XmlDocument xmlInputData, XmlNode activity, Activity newActivity, Process newProcess, string UserName, ref DynamicEvents _dynamicEvents, K2Field SmartObjectServer, string _smartObjectServer, string _ContextType, string _CurrentEnvironment) { using (System.Security.Principal.WindowsImpersonationContext impAppPool = System.Security.Principal.WindowsIdentity.Impersonate(IntPtr.Zero)) { SourceCode.Workflow.Design.ClientEvent newEvent = new SourceCode.Workflow.Design.ClientEvent(); ClientEventItem newEventItem = null;
newEvent.WizardDefinition = new DefaultClientWizardDefinition(); newEventItem = newEvent.EventItem;
newEvent.Name = activity.Attributes["displayname"].Value + " Event"; newEvent.Description = activity.Attributes["displayname"].Value + " Event";
newEventItem.SendToInternet = true; newEventItem.InternetUrl = _dynamicEvents.GetValue(activity.SelectSingleNode("FormPluginData/TaskItem/URL").InnerXml, newProcess, newActivity, SmartObjectServer.Clone<K2Field>(), _ContextType, false, _CurrentEnvironment); XmlNodeList paramaters = activity.SelectNodes("FormPluginData/TaskItem/Parameters/Parameter"); if (paramaters.Count > 0) { newEventItem.InternetUrl.Parts.Add(new ValueTypePart("?")); int count = 0; foreach (XmlNode param in paramaters) { K2Field tempField = _dynamicEvents.GetValue(param.SelectSingleNode("ParameterValue").InnerText, newProcess, newActivity, SmartObjectServer.Clone<K2Field>(), _ContextType, false, _CurrentEnvironment);
if (tempField.Parts[0].GetType().ToString().Equals("SourceCode.Workflow.Design.SerialNoFieldPart")) { newEventItem.InternetUrl.Parts.Add(new ValueTypePart(param.SelectSingleNode("ParameterName").InnerText));
ArrayList input1 = new ArrayList(); ArrayList input2 = new ArrayList(); ArrayList input3 = new ArrayList();
//Text Input input1.Add("System.String"); input1.Add("Text"); input1.Add("The source string."); input1.Add("false"); input1.Add(tempField);
//Find Input input2.Add("System.String"); input2.Add("Find"); input2.Add("The substring to find."); input2.Add("false"); input2.Add(new K2Field(new ValueTypePart("SN=")));
//Find Input input3.Add("System.String"); input3.Add("Replace"); input3.Add("The substring to replace the found substrings."); input3.Add("false"); input3.Add(new K2Field(new ValueTypePart("=")));
K2Field ilFunctField = new K2Field(_dynamicEvents.GetInlineFunctionFieldPart("Replace", "System.String", "SourceCode.Workflow.Functions.TextManipulation, SourceCode.Workflow.Functions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=16a2c5aaaa1b130d", input1, input2, input3)); newEventItem.InternetUrl.Parts.Add(ilFunctField); } else { newEventItem.InternetUrl.Parts.Add(new ValueTypePart(string.Concat(param.SelectSingleNode("ParameterName").InnerText, "="))); newEventItem.InternetUrl.Parts.Add(_dynamicEvents.GetValue(param.SelectSingleNode("ParameterValue").InnerText, newProcess, newActivity, SmartObjectServer.Clone<K2Field>(), _ContextType, false, _CurrentEnvironment)); } count += 1;
if (count < paramaters.Count) { newEventItem.InternetUrl.Parts.Add(new ValueTypePart("&")); } } } newEventItem.InternetPlatform = "ASP";
#region Generic Methods calls //This mthod is in the base class CreateNotification((EventItem)newEventItem, newActivity, activity, xmlProcess, newProcess, SmartObjectServer, _dynamicEvents, _ContextType, _CurrentEnvironment);
//This mthod is in the base class CreateEventActions(activity, newEvent, newProcess);
//This mthod is in the base class CreateOutcomes(newActivity, activity, xmlProcess, newProcess, SmartObjectServer, _dynamicEvents, _ContextType, _CurrentEnvironment); newEvent.WizardDefinition.Status = WizardStatus.Executed; newActivity.Events.Add(newEvent); SourceCode.Workflow.Design.Outcome.Common.SyncActivityAndEventSucceedingRule(newEvent); #endregion } } } } |
![]() |
It is important to note that the method needs to be defined as below to allow the backend to call the correct method upon deployment:: public void CreateDynamicClientEvent(XmlDocument xmlProcess, XmlDocument xmlInputData, XmlNode activity, Activity newActivity, Process newProcess, string UserName, ref DynamicEvents _dynamicEvents, K2Field SmartObjectServer, string _smartObjectServer, string _ContextType, string _CurrentEnvironment) |
![]() |
The following needs to be called to resolve the textbox values from the user interface: _dynamicEvents.GetValue |
* The Custom User Task wizard is only available in K2 blackpearl.